﻿using System;
using System.Text;
using Microsoft.Practices.Unity.InterceptionExtension;

namespace cludg.Infrastructure.DI.Unity
{
	using Core.Logging;
	using Core.Attributes;

	public class LogInvokeHandler : ICallHandler, ILogInvokeHandler
	{
		public int Order { get; set; }

		public ILogger Logger { get; set; }

		public LogInvokeHandler(ILogger logger)
		{
			Logger = logger;
		}

		public IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext)
		{
			try
			{
				var sb = new StringBuilder(input.Target.GetType().FullName)
					.Append(".")
					.Append(input.MethodBase.Name)
					.Append("(");

				for (int i = 0; i < input.Inputs.Count; i++)
				{
					object target = input.Inputs[i];
					if (i > 0)
						sb.Append(", ");
					sb.Append(target ?? "<null>");
				}

				sb.Append(")");
				Logger.DebugFormat("INVOKE {0}", sb);

				var result = getNext()(input, getNext);

				if (result.Exception != null)
				{
					Logger.Error(string.Format("Exception occures in {0}.", sb), result.Exception);
				}
				else
				{
					Logger.DebugFormat("RESULT of {0} is: {1}", sb, result.ReturnValue ?? "<null>");
				}

				return result;
			}
			catch (Exception e)
			{
				Logger.Error("Error in LogInvokeHandler", e);
				return input.CreateExceptionMethodReturn(e);
			}

		}
	}
}
